﻿using AutoMapper;
using Comm100.Application.Services;
using Comm100.Framework.Auditing;
using Comm100.Framework.Authorization;
using Comm100.Public.Audit;
using Bot.Application.Dto;
using Bot.Application.Services;
using Bot.Domain.Bo;
using Bot.Domain.Entities;
using Bot.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using Bot.Domain;

namespace Bot.Application.Intents.Service
{
    public class IntentAppService : BaseAppService, IIntentAppService
    {
        private IIntentDomainService _domainService;
        private IIntentVerifyDataManager _intentVerifyDataManager;

        public IntentAppService(IIntentDomainService domainService,
            IIntentVerifyDataManager intentVerifyDataManager) : base()
        {
            this._domainService = domainService;
            _intentVerifyDataManager = intentVerifyDataManager;
        }

        [Authorization(BotPermission.MANAGE_BOTS)]
        //[Audit(BotEntity.INTENT, AuditAction.DESTROY)]
        public void Delete(Guid id)
        {
            var errorInfo = _intentVerifyDataManager.VerifyDelete(id);
            if (errorInfo != null
                && errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            _domainService.Delete(id);
        }

        [Authorization(BotPermission.MANAGE_BOTS)]
        //[Audit(BotEntity.INTENT, AuditAction.CREATE)]
        public Dto.IntentDto Add(Guid botId, IntentCreateDto dto)
        {
            var errorInfo = _intentVerifyDataManager.VerifyCreate(botId, dto);
            if (errorInfo != null
                && errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            Intent intent = _domainService.Create(botId, Mapper.Map<Intent>(dto));
            return Mapper.Map<Dto.IntentDto>(intent);
        }

        [Authorization(BotPermission.MANAGE_BOTS)]
        //[Audit(BotEntity.INTENT, AuditAction.UPDATE)]
        public Dto.IntentDto Update(Guid id, IntentUpdateDto dto)
        {
            var errorInfo = _intentVerifyDataManager.VerifyUpdate(id, dto);
            if (errorInfo != null
                && errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            Intent intent = _domainService.Update(Mapper.Map<IntentUpdateBo>(dto));
            return Mapper.Map<Dto.IntentDto>(intent);
        }

        public Dto.IntentDto Get(Guid id, string include = "")
        {
            var errorInfo = _intentVerifyDataManager.VerifyGet(id);
            if (errorInfo != null
             && errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            Intent intent = _domainService.Get(id, include);
            return Mapper.Map<Dto.IntentDto>(intent);
        }

        public IEnumerable<Dto.IntentDto> GetList(Guid botId, string include, Guid? categoryId, string keyword)
        {
            var errorInfo = _intentVerifyDataManager.VerifyGetList(botId, include, categoryId, keyword);
            if (errorInfo != null
                && errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            IEnumerable<Intent> list = _domainService.List(botId, include, categoryId, keyword);
            return Mapper.Map<IEnumerable<Dto.IntentDto>>(list);
        }

        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="botId"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public OperationDto Import(Guid botId, string filePath)
        {
            //OperationDto operationDto = _domainService.ImportIntentAsync(headGuid,filePath,botDto,mode);
            return Mapper.Map<OperationDto>(null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="botId"></param>
        /// <param name="question"></param>
        /// <param name="top"></param>
        /// <returns></returns>
        public List<IntentScoreDto> QueryTopScore(Guid botId, string question, int top = 10)
        {
            List<IntentScore> list = new List<IntentScore> { };
            //OperationDto operationDto = _domainService.ImportIntentAsync(headGuid,filePath,botDto,mode);
            return Mapper.Map<List<IntentScoreDto>>(list);
        }
        /// <summary>
        /// query intent
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="detectIntentRequestBodyDto"></param>
        /// <returns></returns>
        public Dto.DetectIntentResponseDto DetectIntent(Guid sessionId, DetectIntentRequestBodyDto detectIntentRequestBodyDto)
        {
            var detectIntentRequestBody = Mapper.Map<DetectIntentRequestBody>(detectIntentRequestBodyDto);
            DetectIntentResponse detectIntentResponse = _domainService.DetectIntent(sessionId, detectIntentRequestBody);
            return Mapper.Map<Dto.DetectIntentResponseDto>(detectIntentResponse);
        }
        /// <summary>
        /// goto intent
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="triggerAnIntentRequestBodyDto"></param>
        /// <returns></returns>
        public TriggerAnIntentResponseDto TriggerAnIntent(Guid sessionId, TriggerAnIntentRequestBodyDto triggerAnIntentRequestBodyDto)
        {
            var triggerAnIntentRequestBody = Mapper.Map<TriggerAnIntentRequestBody>(triggerAnIntentRequestBodyDto);
            TriggerAnIntentResponse triggerAnIntentResponse = _domainService.TriggerAnIntent(sessionId, triggerAnIntentRequestBody);
            return Mapper.Map<TriggerAnIntentResponseDto>(triggerAnIntentResponse);
        }
        /// <summary>
        /// via form
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="submitFormRequestBodyDto"></param>
        /// <returns></returns>
        public HighConfidenceAnswerDto SubmitForm(Guid sessionId, SubmitFormRequestBodyDto submitFormRequestBodyDto)
        {
            var submitFormRequestBody = Mapper.Map<SubmitFormRequestBody>(submitFormRequestBodyDto);
            HighConfidenceAnswer highConfidenceAnswer = _domainService.SubmitForm(sessionId, submitFormRequestBody);
            return Mapper.Map<HighConfidenceAnswerDto>(highConfidenceAnswer);
        }

        /// <summary>
        /// 授权
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="submitAuthenticationRequestBodyDto"></param>
        /// <returns></returns>
        public HighConfidenceAnswerDto SubmitAuthentication(Guid sessionId, SubmitAuthenticationRequestBodyDto submitAuthenticationRequestBodyDto)
        {
            var submitAuthenticationRequestBody = Mapper.Map<SubmitAuthenticationRequestBody>(submitAuthenticationRequestBodyDto);
            HighConfidenceAnswer highConfidenceAnswer = _domainService.SubmitAuthentication(sessionId, submitAuthenticationRequestBody);
            return Mapper.Map<HighConfidenceAnswerDto>(highConfidenceAnswer);
        }
        /// <summary>
        /// share location
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="submitLocationRequestBodyDto"></param>
        /// <returns></returns>
        public HighConfidenceAnswerDto SubmitLocation(Guid sessionId, SubmitLocationRequestBodyDto submitLocationRequestBodyDto)
        {
            var submitLocationRequestBody = Mapper.Map<SubmitLocationRequestBody>(submitLocationRequestBodyDto);
            HighConfidenceAnswer highConfidenceAnswer = _domainService.SubmitLocation(sessionId, submitLocationRequestBody);
            return Mapper.Map<HighConfidenceAnswerDto>(highConfidenceAnswer);
        }
        /// <summary>
        /// rate
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="rateRequestBodyDto"></param>
        /// <returns></returns>
        public NotHelpfulAnswerDto Rate(Guid sessionId, RateRequestBodyDto rateRequestBodyDto)
        {
            var rateRequestBody = Mapper.Map<RateRequestBody>(rateRequestBodyDto);
            NotHelpfulAnswer notHelpfulAnswer = _domainService.Rate(sessionId, rateRequestBody);
            return Mapper.Map<NotHelpfulAnswerDto>(notHelpfulAnswer);
        }
    }
}
